#include "head.h"
//处理长命令函数
int deal_longcmd(pool_t pool, int net_fd){
    // 共享资源的访问加锁
    pthread_mutex_lock(&pool.pthread_lock);
    // 入队
    en_queue(&pool.queue, net_fd);
    // 唤醒一个子线程去队列中拿任务/客户端连接
    pthread_cond_signal(&pool.cond);
    // 解锁
    pthread_mutex_unlock(&pool.pthread_lock);                                         
    return 0;
}
//处理短指令
int deal_short_cmd(int net_fd,MYSQL * conn,char * uname,char *cur_path,char *last_deleted_file,char * last_deleted_path){
    // 接收命令
    char buf_cmd[100] = {0};
    int res_recv = recv(net_fd, buf_cmd, sizeof(buf_cmd), 0);
    ERROR_CHECK(res_recv, -1, "recv");

    if (strcmp(buf_cmd, "") != 0){

        printf("client cmd: %s\n", buf_cmd);
        // 将命令头转换为枚举类型
        char *cmd_head;
        char *cmd_body;
        COMMAND cmd;
        if (strcmp(buf_cmd, "ls") == 0) {
            cmd = ls;
        }else if (strcmp(buf_cmd, "pwd") == 0) {
            cmd = pwd;

        }else if(strcmp(buf_cmd, "undorm") == 0){
            cmd = undo_rm;
        }
        else {
            // 分析命令: 切割命令，获取命令头，命令体
            cmd_head = strtok(buf_cmd, " ");
            printf("cmd head : %s\n", cmd_head);
            if (strcmp(cmd_head, "cd") == 0) {
                cmd = cd;
                cmd_body = strtok(NULL,  " ");
                //printf("cmd body : %s\n", cmd_body);
            } else if (strcmp(cmd_head, "mkdir") == 0) {
                cmd = mk_dir;
                cmd_body = strtok(NULL, "\n");
                //printf("cmd body : %s\n", cmd_body);
            } else if (strcmp(cmd_head, "rm") == 0) {
                cmd = rm_dir;
                cmd_body = strtok(NULL,  "\n");
                //printf("cmd body : %s\n", cmd_body);
            } // 无需判错，客户端已做相应处理
        }

        // 根据命令调用相应函数
        switch (cmd){
        case ls: client_ls(conn, net_fd, uname, cur_path); break;
        case pwd: send(net_fd, cur_path, strlen(cur_path), MSG_NOSIGNAL); break;
        case mk_dir:client_mkdir(cur_path, net_fd, cmd_body, conn, uname); break;
        case rm_dir: client_rm(conn, net_fd,  cur_path,cmd_body, last_deleted_file, last_deleted_path); break;
        case cd: client_cd( net_fd,conn, cmd_body,cur_path); break;
        case undo_rm:client_undo_rm(conn, net_fd, last_deleted_file, last_deleted_path);break;
        default:break;
        }

        printf("operate finished\n");
        //close(net_fd);
    }
    return 0;
}





//ls命令
int client_ls(MYSQL *conn, int net_fd, char *uname, char *cur_path){
    MYSQL_RES *res;
    MYSQL_ROW row;
    char query[1024];


    // 构建 SQL 查询，获取当前目录下的所有文件和目录
    snprintf(query, sizeof(query),
             "SELECT f_name, f_type, f_create_time, f_last_modify FROM files WHERE f_father = (select f_id from files where f_path = '%s' AND f_owner = '%s') AND f_exist = 1", cur_path, uname);
    if (mysql_query(conn, query)) {
        fprintf(stderr, "Error when executing query: %s\n", mysql_error(conn));
        return -1;
    }

    res = mysql_store_result(conn);
    mysql_error(conn);
    if (res == NULL) {
        fprintf(stderr, "Failed to retrieve query result: %s\n", mysql_error(conn));
        return -1;
    }
    // 遍历查询结果

    //<<<<<< 客户端接收ls的反馈需要循环读>>>>>>>
    int flag = 0;
    while ((row = mysql_fetch_row(res))) {
        //printf("row[1] = %d\n", row[1]);
        //printf("row[1] = %d\n", atoi(row[1]));
        flag = 1;
        char msg[1024] = { 0 };
        snprintf(msg, 1024,"%s %s | 创建时间: %s | 最后修改时间: %s\n", row[1][0] == '1' ? "<DIR>" : "<FILE>", row[0], row[2], row[3]);
        send(net_fd, msg, strlen(msg), MSG_NOSIGNAL);
        usleep(1000);//去掉可能不管用
    }
    //while循环结束时 row为NULL

    if(row == NULL && flag ==0){//只有当row为NULL，且flag为0时才表示当前目录为空目录
        char msg[1024] = { 0 };
        snprintf(msg, 1024,"当前目录为空！\n");
        send(net_fd, msg, strlen(msg), MSG_NOSIGNAL);
        usleep(1000);//同理
    } 
    send(net_fd, "1", strlen("1"), MSG_NOSIGNAL);
    mysql_free_result(res);
    return 0;
}


// 删除指定文件或目录
int client_rm(MYSQL *conn, int net_fd, char *cur_path, const char *file_name, char *last_deleted_file, char *last_deleted_path) {
    char query[1024];

    //printf("cur_path:%s\n",cur_path);
    // 构建更新SQL语句，设置f_exist为0
    if(strcmp(cur_path, "/") == 0){
        snprintf(query, sizeof(query),
                 "UPDATE files SET f_exist = 0 WHERE f_name = '%s' AND f_path = '%s%s'",
                 file_name, cur_path, file_name);
    }else{
        snprintf(query, sizeof(query),
                 "UPDATE files SET f_exist = 0 WHERE f_name = '%s' AND f_path = '%s/%s'",
                 file_name, cur_path, file_name);
    }

    printf("%s\n",query);
    // 执行SQL查询
    if (mysql_query(conn, query)) {
        fprintf(stderr, "删除文件错误: %s\n", mysql_error(conn));
        return -1;
    }


    // 检查是否成功更新了记录
    if (mysql_affected_rows(conn) == 0) {
        char msg[1024] = { 0 };
        snprintf(msg, 1024, "未找到文件或目录 %s 或已经被删除。\n", file_name);
        send(net_fd, msg, strlen(msg), MSG_NOSIGNAL);
        return -1;
    }
    //记录本次删除的文件信息
    if(strcmp(cur_path, "/") == 0){
        strcpy(last_deleted_file, file_name);
        snprintf(last_deleted_path, 1024, "%s%s", cur_path, file_name);
    }else{
        strcpy(last_deleted_file, file_name);
        snprintf(last_deleted_path, 1024, "%s/%s", cur_path, file_name);
    }
    //printf("cur_path:%s\n", cur_path);
   // printf("file_name:%s\n", file_name);
  //  printf("删除路径:%s\n", last_deleted_path);
    char msg[1024] = { 0 };
    snprintf(msg, 1024, "文件或目录 %s 已被删除（使用“undorm”命令撤销本次删除）。\n", file_name);
    send(net_fd, msg, strlen(msg), MSG_NOSIGNAL);
    return 0;
}
//撤销最近一次删除
int client_undo_rm(MYSQL *conn, int net_fd, char *last_deleted_file, char *last_deleted_path) {
    if (strlen(last_deleted_file) == 0) {
        char msg[1024] = { 0 };
        snprintf(msg, 1024, "没有可撤销的删除操作。\n");
        send(net_fd, msg, strlen(msg), MSG_NOSIGNAL);
        return -1;
    }

    char query[1024];
    snprintf(query, sizeof(query), "UPDATE files SET f_exist = 1 WHERE f_name = '%s' AND f_path = '%s'", last_deleted_file, last_deleted_path);
    if (mysql_query(conn, query)) {
        fprintf(stderr, "撤销删除错误: %s\n", mysql_error(conn));
        return -1;
    }
    //printf("%s\n",query);
    if (mysql_affected_rows(conn) == 0) {
        char msg[1024] = { 0 };
        snprintf(msg, 1024, "未能撤销删除，文件或目录 %s 可能已经彻底删除。\n", last_deleted_file);
        send(net_fd, msg, strlen(msg), MSG_NOSIGNAL);
        return -1;
    }

    char msg[1024] = { 0 };
    snprintf(msg, 1024, "文件或目录 %s 的删除已成功撤销。\n", last_deleted_file);
    send(net_fd, msg, strlen(msg), MSG_NOSIGNAL);
    // 清空记录
    last_deleted_file[0] = '\0';
    last_deleted_path[0] = '\0';
    return 0;
}

//mkdir
/*int client_mkdir(char *cur_path, int net_fd, char *order, MYSQL* mysql, char *uname){

    // test 

    MYSQL_RES *result;
    MYSQL_ROW row;


    //f_name数组存储order，并将其末尾的回车去掉
    char *f_path = cur_path;
    char f_name[100]= {0};
    //printf("-----------\n");
    strncpy(f_name, order, strlen(order));

    //printf("f_name:%s\n",f_name);
    char new_dir_path[1024] = {0};//新创建的文件的路径名
    char sql_order[1024] = {0};//要执行的sql命令
    //组合新路径名
    strcpy(new_dir_path, f_path);
    //printf("new_dir_path:%s\n",new_dir_path);
    if(strlen(f_path) == 1){
        strcat(new_dir_path,f_name);
    }
    else{
        strcat(strcat(new_dir_path, "/"), f_name);
    }

    //printf("121245\n");

    //设置f_exist和f_type
    int f_exist = 1;
    int f_type = 1;

    //查找文件拥有者
    //char owner[1024] = {0};//拥有者名字
    char select_order[1024] = {0};//要用sql执行的命令
    //查找父id
    bzero(select_order,sizeof(select_order));//初始化字符串数组
    //拼接命令
    sprintf(select_order, "select f_id from files where f_path like '%s'", f_path);
    mysql_query(mysql, select_order);
    //printf("123\n");
    //select查找父id
    result = mysql_store_result(mysql);
    row = mysql_fetch_row(result);
    int father_id = atoi(row[0]);
    mysql_free_result(result);
    //printf("193\n");
    //检查重名
    bzero(select_order, sizeof(select_order));
    sprintf(select_order, "select f_id from files where f_path like '%s'", new_dir_path);
    printf("%s\n",select_order);
    mysql_query(mysql, select_order);
    //printf("198\n");
    result = mysql_store_result(mysql);
    row = mysql_fetch_row(result);

    //row 为NULL时没重名
    if(row != NULL){
        //printf("ifif\n");
        send(net_fd, "make fail!", strlen("delet fail!"), MSG_NOSIGNAL);
    }
    else{
        //printf("elseelse\n");
        //组合sql命令
        sprintf(sql_order, "insert into files (f_name, f_exist, f_owner, f_father, f_path, f_type, f_create_time, f_last_modify, f_finsh) values ('%s', %d, '%s', %d, '%s', %d, NOW(), NOW(), 1)", f_name, f_exist, uname, father_id, new_dir_path, f_type);

        //printf("%s\n",sql_order);

        send(net_fd, "make success!", strlen("make success!"), MSG_NOSIGNAL);
        mysql_query(mysql,sql_order);
    }

    return 0;
}
*/
int client_mkdir(char *cur_path, int net_fd, const char *dir_name, MYSQL *conn, char *uname) {
    MYSQL_RES *res;
    MYSQL_ROW row;
    char query[1024];
    int f_father = -2;  // 假设 -2 为无效值，表示未找到


    // 先查询当前目录的 f_father 值
    snprintf(query, sizeof(query), "SELECT f_id FROM files WHERE f_path = '%s' AND f_type = '1' AND f_owner = '%s'", cur_path, uname);
    if (mysql_query(conn, query)) {
        fprintf(stderr, "查询父目录失败: %s\n", mysql_error(conn));
        return -1;
    }
    res = mysql_store_result(conn);
    if (res == NULL) {
        fprintf(stderr, "获取查询结果失败: %s\n", mysql_error(conn));
        return -1;
    }
    if((row = mysql_fetch_row(res)) != NULL){
        f_father = atoi(row[0]);  
    }
    mysql_free_result(res);

    if (f_father == -2) {
        fprintf(stderr, "未找到当前目录的父ID。\n");
        return -1;
    }
    //判断当前路径下是否已创建该文件
    snprintf(query, sizeof(query), "SELECT f_name FROM files WHERE  f_father = '%d' AND f_owner = '%s' AND f_exist = '1' AND f_type = '1'", f_father, uname);
    mysql_query(conn , query);
    res = mysql_store_result(conn);
    //打印查找到的数据
    while((row = mysql_fetch_row(res))){
        if(strcmp(row[0], dir_name) == 0){
            char msg[1024] = { 0 };
            snprintf(msg, 1024, "当前路径下已存在该文件夹\n");
            send(net_fd, msg, strlen(msg), MSG_NOSIGNAL);
            return -1;
        }   
    }   
    mysql_free_result(res);

    // 插入新目录记录
    if(strcmp(cur_path, "/") != 0){
        snprintf(query, sizeof(query),
                 "INSERT INTO files (f_name, f_owner, f_father, f_path, f_type, f_finsh, f_create_time, f_last_modify) "
                 "VALUES ('%s', '%s', %d, '%s/%s', '1', '1', NOW(), NOW())", dir_name, uname, f_father, cur_path, dir_name);
    }else{
        snprintf(query, sizeof(query),
                 "INSERT INTO files (f_name, f_owner, f_father, f_path, f_type, f_finsh, f_create_time, f_last_modify) "
                 "VALUES ('%s', '%s', %d, '%s%s', '1', '1', NOW(), NOW())", dir_name, uname, f_father, cur_path, dir_name);

    }
    printf("%s\n", query);
    if (mysql_query(conn, query)) {
        fprintf(stderr, "创建目录失败: %s\n", mysql_error(conn));
        return -1;
    }

    char msg[1024] = { 0 };
    snprintf(msg, 1024, "目录 '%s' 已成功创建于 '%s'.\n", dir_name, cur_path);
    send(net_fd, msg, strlen(msg), MSG_NOSIGNAL);
    return 0;
}




//和客户端通信的net_fd,数据库，命令参数，当前路径
int client_cd(int net_fd,MYSQL *conn,char *order,char *cur_path){

    //buf保存cur_path
    char buf[100]={0};
    memcpy(buf,cur_path,strlen(cur_path));
    //path数组存储order，并将其末尾的回车去掉
    char path[100]={0};
    memcpy(path,order,strlen(order));
    //printf("命令参数path:%s,len(path):%ld\n",path,strlen(path));



    MYSQL_RES * result;
    MYSQL_ROW * row;
    char query[1000]={0};
    //path_temp存储本次要访问的文件路径,带斜线
    char path_temp[100]="/";
    //printf("path_temp:%ld\n",strlen(path_temp));
    //切割遍历path，看目录是否合法
    //ch存储当前切割的第一层目录
    char *ch=strtok(path,"/");
    while(ch!=NULL){
        if(strlen(cur_path)==1){
            strcat(path_temp,ch);// /code
        }else{
            //cur_path初始长度不为1
            bzero(path_temp,sizeof(path_temp));
            memcpy(path_temp,cur_path,strlen(cur_path));
            strcat(path_temp,"/");
            strcat(path_temp,ch);
        }

        if(strcmp(path,"..")==0){
            if(strlen(cur_path)==1){
                //send(net_fd,"您已处在根目录\n",100,0);
                break;
            }else{
                bzero(path_temp,sizeof(path_temp));
                memcpy(path_temp,cur_path,strlen(cur_path));
                //last_slash指向最后一个斜杠
                char *last_slash=strrchr(path_temp,'/');
                if(last_slash!=NULL){
                    *last_slash='\0';
                    //printf("strlen_path长度:%ld\n",strlen(path_temp));
                    if(strlen(path_temp)==0){
                        //printf("strlen(path_temp)=0\n");
                        strcpy(path_temp,"/");//路径为空，设为根目录
                        //printf("path_temp:%s,len(path_temp):%ld\n",path_temp,strlen(path_temp)); 
                    }
                }
            }
        }

        bzero(query,sizeof(query));
        //printf("path_temp:%s,len(path_temp):%ld\n",path_temp,strlen(path_temp));
        sprintf(query,"select f_exist,f_type from files where f_path='%s'",path_temp);
       // printf("len(query):%ld,query:%s\n",strlen(query),query);
        if(mysql_query(conn,query)){
            //printf("进入if\n");
            //printf("%s\n",mysql_error(conn));
            return 1;
        }
        result=mysql_store_result(conn);
        if(mysql_num_rows(result)==0){
            mysql_free_result(result);
            printf("没有这个目录\n");
            send(net_fd,"访问的目录不存在\n",100,0);
            memcpy(cur_path,buf,strlen(buf));
    usleep(1000);
            send(net_fd,cur_path,strlen(cur_path),0);
            exit(1);
        }
        row = mysql_fetch_row(result);
        //printf("f_exist:%s,f_type:%s\n",row[0],row[1]);
        //不是目录或者存在位不为1
        if((atoi(row[1])!=1)||(atoi(row[0])!=1)){
            send(net_fd,"访问的路径不存在\n",100,0);
    usleep(1000);
            send(net_fd,cur_path,strlen(cur_path),0);
            exit(1);
        }
        ch=strtok(NULL,"/");
        mysql_free_result(result);

        bzero(cur_path,sizeof(cur_path));
        strcpy(cur_path,path_temp);
        //memcpy(cur_path,path_temp,strlen(path_temp));
    }

    //printf("当前路径:%s\n",cur_path);
    send(net_fd ,"cd success!\n", strlen("cd success!\n"), 0);
    usleep(1000);
    send(net_fd,cur_path, 1024,0);
}
/*int client_cd(int net_fd, MYSQL *conn, const char *dir_name, char *cur_path){
    MYSQL_RES *res;
    MYSQL_ROW row;
    char query[1024];

    // 如果命令是 'cd ..'，则处理返回上一级目录
    if (strcmp(dir_name, "..") == 0) {
        if (strcmp(cur_path, "/") != 0) {  // 确保当前路径不是根目录
            char *last_slash = strrchr(cur_path, '/');
            if (last_slash != NULL) {
                *last_slash = '\0';  // 删除最后一个斜杠后的内容
                if (strlen(cur_path) == 0) {
                    strcpy(cur_path, "/");  // 如果路径为空，设为根目录
                }
            }
            char msg[1024] = { 0 };
            snprintf(msg, 1024, "已切换到：%s", cur_path);
            send(net_fd, msg, strlen(msg), MSG_NOSIGNAL);
            send(net_fd, cur_path, strlen(cur_path), MSG_NOSIGNAL);
            return 0;  // 成功返回到上一级目录
        }
        send(net_fd, "已在根目录，无法返回！\n", strlen("已在根目录，无法返回！\n"), MSG_NOSIGNAL);
        send(net_fd, cur_path, strlen(cur_path), MSG_NOSIGNAL);
        return -1;  // 已在根目录，无法返回
    }
    // 构建查询以检查目标目录是否存在
    snprintf(query, sizeof(query), "SELECT f_path FROM files WHERE f_name = '%s' AND f_type = '1' AND f_path LIKE '%s%%' AND f_exist = 1", dir_name, cur_path);
    printf("%s\n", query);
    if (mysql_query(conn, query)) {
        fprintf(stderr, "Error: %s\n", mysql_error(conn));
        return -1;
    }

    res = mysql_store_result(conn);
    if (res == NULL) {
        fprintf(stderr, "Error: %s\n", mysql_error(conn));
        return -1;
    }

    // 检查是否有结果
    if ((row = mysql_fetch_row(res)) != NULL) {
        // 更新当前路径
        char msg[1024] = { 0 };
        strcpy(cur_path, row[0]);
        snprintf(msg, 1024, "已切换到：%s", dir_name);
        send(net_fd, msg, strlen(msg), MSG_NOSIGNAL);
        send(net_fd, cur_path, strlen(cur_path), MSG_NOSIGNAL);
    }

    mysql_free_result(res);
    return 0;
}
*/
